package models.weixin.crop;

import models.enums.WxcpAppStatus;
import models.enums.WxcpAppType;
import models.weixin.crop.bean.WxCpAgent;
import models.weixin.crop.bean.WxCpCorp;
import helper.GlobalConfig;
import models.constants.DeletedStatus;
import play.Logger;
import play.db.jpa.Model;
import play.modules.paginate.JPAExtPaginator;

import javax.persistence.*;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 微信企业号公司信息.
 *
 * 企业号应用可以有多个公司运行，需要后台可以开通公司，开通后，会生成一个对接api url.
 *
 */
@Entity
@Table(name = "wxcp_corps")
public class Corp extends Model {

    public static final  String LOGIN_ID             = "user_loginId"; //登陆ID
    public static final  String LOGIN_NAME           = "loginName"; //登陆密码
    public static final  String LOST_USER_ID         = "lostUserId"; // 找回密码时候用到的Session
    public static final  String LOGIN_SESSION_USER   = "LoginUser_";
    public static final  String PHONE_VALIDATE_TIMES = "Phone_Validate_Times";
    private static final long   serialVersionUID     = 2612836035231152552L;

    /**
     * 公司编码.
     * <p/>
     * 公司缩写，需要保证系统中唯一，考虑将来做公司首页用.
     * 默认直接使用wxCorpId
     */
    @Column(name = "code", length = 20, unique = true)
    public String code;

    /**
     * 公司名.
     */
    @Column(name = "name", length = 50)
    public String name;

    /**
     * 微信企业号分配的 CorpID.
     */
    @Column(name = "wx_corp_id", length = 50)
    public String wxCorpId;

    /**
     * 微信企业号 CorpSecret.
     * <p/>
     * 在 设置 -> 管理组 中加入新的管理组，然后配置权限，最下面可以看到开发者凭证，复制其Secret即可
     * 可参考： http://www.welltalk.com.cn/help/help/qyhyy.html
     */
    @Column(name = "wx_secret", length = 100)
    public String wxSecret;

    /**
     * 冻结
     */
    @Column(name = "is_enabled")
    public Boolean enabled;

    /**
     * 失效时间.
     * <p/>
     * 如果有值，则在此值之前此公司是可用的.
     * 如果无值，则依赖于enabled值.
     */
    @Column(name = "expired_at")
    public Date expiredAt;

    /**
     * 创建时间.
     */
    @Column(name = "created_at")
    public Date createdAt;

    /**
     * 更新时间.
     */
    @Column(name = "updated_at")
    public Date updatedAt;

    /**
     * 最大用户数
     */
    @Column(name = "user_max")
    public Integer userMax;

    /**
     * 最大应用数.
     */
    @Column(name = "agent_max")
    public Integer agentMax;
    /**
     * 逻辑删除,0:未删除，1:已删除
     */
    @Enumerated(EnumType.ORDINAL)
    public DeletedStatus deleted = DeletedStatus.UN_DELETED;
    @Transient
    public List<CorpApp> getCorpApps() {
        return find(" corp=?", this).fetch();
    }

    /**
     * 查找有效的Corp.
     *
     * @param corpCode
     * @return
     */
    public static Corp findAvailableByCode(String corpCode) {
        return Corp.find(" code=? and enabled=? and expiredAt >= ?",
                corpCode, Boolean.TRUE, new Date()).first();
    }

    public static Corp findValidCorp(Long corpId) {
        return find(" id = ? ", corpId).first();
    }


    public static Corp findByLoginToken(String corpToken) {
        return Corp.find("loginToken = ?", corpToken).first();
    }

    /**
     * @return boolean  True 表示 帐号密码正确  false 表示帐号密码不正确
     * @throws
     * @Title: getLoginUser
     * @Description: 判断登陆用户 帐号 密码是否正确
     * @author YangShanCHeng
     */
    //FIXME: 这个方法不应该使用，公司登录不是用这个。。。。
    public static Corp getLoginCorp(String loginName, String password) {
        Corp corp = Corp.find(" name= ? or code=?", loginName, loginName).first();

        if (corp == null) {
            return null;
        } else {
            Logger.info("cord = " + corp + "--------------------------" );
            return corp;
        }
    }

    /**
     * 按appType找到对应的应用.
     *
     * @param appType
     * @return
     */
    public CorpApp findAppByType(String appType) {
        WxcpAppType wxcpAppType = WxcpAppType.valueOf(appType.toUpperCase());
        if (wxcpAppType == null) {
            return null;
        }
        return find(" corp=? and appType=? and status=? and (expiredAt >= ? or expiredAt is null)",
                this, wxcpAppType, WxcpAppStatus.OPEN, new Date()
        ).first();
    }

    /**
     * 从微信信息中查找或建立Corp对象.
     *
     * @param wxCpCorp
     * @return Corp
     */
    public static Corp findOrCreateFromWxCp(WxCpCorp wxCpCorp) {
        Corp corp = Corp.find("  wxCorpId=? order by id desc", wxCpCorp.id).first();
        if (corp == null) {
            corp = new Corp();
            corp.code = wxCpCorp.id;
            corp.wxCorpId = wxCpCorp.id;
            corp.name = wxCpCorp.name;
            corp.enabled = Boolean.TRUE;
            corp.createdAt = new Date();
            corp.updatedAt = new Date();
            corp.userMax = wxCpCorp.userMax;
            corp.agentMax = wxCpCorp.agentMax;
            corp.deleted=models.constants.DeletedStatus.UN_DELETED;
            corp.save();

        } else {
            Logger.info("找到corp:" + corp);
        }
        for (WxCpAgent agent : wxCpCorp.agents) {
            Logger.info("agent=%s", agent);
            if (String.valueOf(GlobalConfig.WXCP_SUITE_ZAINR_APPID).equals(agent.appId)) {

                Logger.info("找到对应的ZAINR应用");

                CorpApp corpApp = CorpApp.findByType(corp, WxcpAppType.TRIP);
                Logger.info("corpApp=%s", corpApp);
                if (corpApp == null) {
                    Logger.info("=======> corpApp为空，重新建立并更新");
                    corpApp = new CorpApp();
                    corpApp.corp = corp;
                    corpApp.createdAt = new Date();
                    corpApp.appType = WxcpAppType.TRIP;
                    corpApp.fromSuite = Boolean.TRUE;
                    corpApp.subdomain = corp.wxCorpId;
                    corpApp.name = GlobalConfig.WXCP_SUITE_ZAINR_APPNAME;
                }
                corpApp.appType = WxcpAppType.TRIP;
                corpApp.wxAgentId = agent.id;
                corpApp.status = WxcpAppStatus.OPEN;
                corpApp.updatedAt = new Date();
                corpApp.permanentCode = wxCpCorp.permanentCode;
                corpApp.save();
            }
        }

        return corp;
    }

    /**
     * 得到应用的请求URL中HOST地址.
     */
    public String urlHost() {
        return code + "." + GlobalConfig.WEIXIN_BASE_DOMAIN;
    }

    @Override public String toString() {
        final StringBuilder sb = new StringBuilder("Corp{");
        sb.append("code='").append(code).append('\'');
        sb.append(", name='").append(name).append('\'');
        sb.append(", wxCorpId='").append(wxCorpId).append('\'');
        sb.append(", wxSecret='").append(wxSecret).append('\'');
        sb.append(", enabled=").append(enabled);
        sb.append(", expiredAt=").append(expiredAt);
        sb.append(", createdAt=").append(createdAt);
        sb.append(", updatedAt=").append(updatedAt);
        sb.append(", userMax=").append(userMax);
        sb.append(", agentMax=").append(agentMax);
        sb.append(", deleted=").append(deleted);
        sb.append('}');
        return sb.toString();
    }

    /**
     * 分页查询.
     */
    public static JPAExtPaginator<Corp> findByCondition(Map<String, Object> conditionMap, String orderByExpress, int pageNumber, int pageSize) {

        StringBuilder xsqlBuilder = new StringBuilder(" t.deleted=models.constants.DeletedStatus.UN_DELETED ")
                .append("/~ and t.id = {id} ~/")
                .append("/~ and t.code = {code} ~/")
                .append("/~ and t.name like {name} ~/")
                .append("/~ and t.wxCorpId = {wxCorpId} ~/")
                .append("/~ and t.wxSecret = {wxSecret} ~/")
                .append("/~ and t.enabled = {enabled} ~/")
                .append("/~ and t.expiredAt = {expiredAt} ~/")
                .append("/~ and t.createdAt = {createdAt} ~/")
                .append("/~ and t.updatedAt = {updatedAt} ~/")
                .append("/~ and t.agentMax = {agentMax} ~/")
                .append("/~ and t.userMax = {userMax} ~/");

        util.xsql.XsqlBuilder.XsqlFilterResult result = new util.xsql.XsqlBuilder().generateHql(xsqlBuilder.toString(), conditionMap);
        Logger.info("查询语句条件 : " + result.getXsql() + "====");
        JPAExtPaginator<Corp> corpPage = new JPAExtPaginator<Corp>("Corp t", "t", Corp.class,
                result.getXsql(), conditionMap).orderBy(orderByExpress);
        corpPage.setPageNumber(pageNumber);
        corpPage.setPageSize(pageSize);
        corpPage.setBoundaryControlsEnabled(false);
        return corpPage;
    }

//查找所有的公司
    public static  List<Corp> loadAllCorp() {
        return Corp.find("deleted=?", DeletedStatus.UN_DELETED).fetch();
    }

}
